package com.bite.messageQueue.mqServer.core;

import java.io.Serial;
import java.io.Serializable;
import java.util.UUID;

/**
 * 表示消息
 * 在网络上进行传输，也需要写入文件里，所以Message需要支持序列化
 */
public class Message implements Serializable {
    //验证序列化版本
    @Serial
    private static final long serialVersionUID = 1L;
    //属性
    private BasicProperties basicProperties = new BasicProperties();
    //正文
    private byte[] body;

    //辅助属性
    /**
     * 文件中的消息数量很多，如果存在数据库中会影响效率
     * 所以使用文件的方式进行存储
     * offsetBegin表示消息在文件中的起始位置
     * offsetEnd表示消息在文件中的结束位置
     * [offsetBegin，offsetEnd)
     * 不需要被序列化保存到文件中 此时消息一旦被写入文件之后, 所在的位置就固定了. 并不需要单独存储.
     * 存在的目的, 主要就是为了让内存中的 Message 对象, 能够快速找到对应的硬盘上的 Message 的位置.
     */
    private transient long offsetBegin = 0; //消息数据的开头到文件开头的偏移量
    private transient long offsetEnd = 0;   //消息数据的结尾到文件开头的偏移量
    //表示该消息在数据库中是否为有效消息，也就是逻辑删除,0x1表示有效，0x0表示无效
    private byte isValid = 0x1;

    //工厂方法创建信息类
    //这个方法中创建的 Message 对象, 会自动生成唯一的 MessageId
    //万一 routingKey 和 basicProperties 里的 routingKey 冲突, 以外面的为主
    public static Message createMessageWithID(String routingKey, BasicProperties basicProperties, byte[] body) {
        Message message = new Message();
        if(basicProperties != null) {
            message.setBasicProperties(basicProperties);
        }
        message.basicProperties.setRoutingKey(routingKey);
        message.setMessageID("M-" + UUID.randomUUID());
        message.body = body;
        return message;
    }

    public Message() {
    }

    public Message(BasicProperties basicProperties, byte[] body, long offsetBegin, long offsetEnd, byte isValid) {
        this.basicProperties = basicProperties;
        this.body = body;
        this.offsetBegin = offsetBegin;
        this.offsetEnd = offsetEnd;
        this.isValid = isValid;
    }

    public String getMessageID() {
        return basicProperties.getMessageID();
    }

    public void setMessageID(String messageID) {
        basicProperties.setMessageID(messageID);
    }

    public String getRoutingKey() {
        return basicProperties.getRoutingKey();
    }

    public void setRoutingKey(String routingKey) {
        basicProperties.setRoutingKey(routingKey);
    }

    public int getDeliverMode() {
        return basicProperties.getDeliverMode();
    }

    public void setDeliverMode(int deliverMode) {
        basicProperties.setDeliverMode(deliverMode);
    }

    /**
     * 获取
     * @return basicProperties
     */
    public BasicProperties getBasicProperties() {
        return basicProperties;
    }

    /**
     * 设置
     * @param basicProperties
     */
    public void setBasicProperties(BasicProperties basicProperties) {
        this.basicProperties = basicProperties;
    }

    /**
     * 获取
     * @return body
     */
    public byte[] getBody() {
        return body;
    }

    /**
     * 设置
     * @param body
     */
    public void setBody(byte[] body) {
        this.body = body;
    }

    /**
     * 获取
     * @return offsetBegin
     */
    public long getOffsetBegin() {
        return offsetBegin;
    }

    /**
     * 设置
     * @param offsetBegin
     */
    public void setOffsetBegin(long offsetBegin) {
        this.offsetBegin = offsetBegin;
    }

    /**
     * 获取
     * @return offsetEnd
     */
    public long getOffsetEnd() {
        return offsetEnd;
    }

    /**
     * 设置
     * @param offsetEnd
     */
    public void setOffsetEnd(long offsetEnd) {
        this.offsetEnd = offsetEnd;
    }

    /**
     * 获取
     * @return isValid
     */
    public byte getIsValid() {
        return isValid;
    }

    /**
     * 设置
     * @param isValid
     */
    public void setIsValid(byte isValid) {
        this.isValid = isValid;
    }

    @Override
    public String toString() {
        return "Message{basicProperties = " + basicProperties + ", body = " + body + ", offsetBegin = " + offsetBegin + ", offsetEnd = " + offsetEnd + ", isValid = " + isValid + "}";
    }
}
